package com.shop.front.service.user;

import com.alibaba.fastjson.JSON;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import com.shop.common.enums.System.SysConfigConst;
import com.shop.common.enums.System.SystemConfigEnum;
import com.shop.common.enums.TrueFalseEnum;
import com.shop.common.enums.user.AccountTypeEnum;
import com.shop.common.enums.user.BillTableNameEnum;
import com.shop.common.enums.user.IncomeTypeEnum;
import com.shop.domain.system.SystemConfig;
import com.shop.domain.user.*;
import com.shop.front.consts.FrontConst;
import com.shop.front.dao.store.StoreOrderDao;
import com.shop.front.dao.system.SystemConfigDao;
import com.shop.front.dao.user.*;
import com.shop.front.property.BusinessProps;
import com.shop.front.request.user.*;
import com.shop.front.response.FrontRetEnum;
import com.shop.front.response.user.LoginUserResp;
import com.shop.front.service.system.SystemService;
import com.shop.front.shiro.UserTokenUtil;
import com.shop.front.util.tencent.SendSms;
import com.shop.front.vo.user.UserCenterVo;
import com.shop.front.vo.user.UserIncomeStatisticVo;
import com.shop.util.*;
import com.shop.web.cache.RedisCache;
import com.shop.web.context.WebContext;
import com.shop.web.response.BaseResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
import java.util.Properties;
import java.util.Random;


@Transactional
@Service
@Slf4j
public class UserService {


    @Autowired
    private UserDao userDao;

    @Autowired
    private UserSQLDao userSQLDao;

    @Autowired
    private UserExtractDao userExtractDao;
    @Autowired
    private BusinessProps businessProps;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    SystemService systemService;

    @Autowired
    private SystemConfigDao systemConfigDao;
    @Autowired
    private UserExtractSQLDao userExtractSQLDao;
    @Autowired
    private CollectDao collectDao;

    @Autowired
    private StoreOrderDao storeOrderDao;

    @Autowired
    private ProductFeedbackDao productFeedbackDao;

    @Autowired
    private CollectSQLDao collectSQLDao;

    @Autowired
    private UserBankCardDao userBankCardDao;
    @Autowired
    UserBillService userBillService;

    @Autowired
    UserIntegtralBillService userIntegtralBillService;


    public User authUserIdByAccessToken(String accessToken) {
        if (StringUtils.isBlank(accessToken)) return null;

        // 从缓存中获取加密userId
        String hexUserId = redisCache.getString(FrontConst.USER_HEXUSERID + accessToken);
        if (StringUtils.isBlank(hexUserId)) {
            return null;
        }

        // 解密
        String sourceStr = CodecUtil.buildAESDecrypt(hexUserId, businessProps.getTokenAesKey());
        if (StringUtils.isBlank(sourceStr)) {
            return null;
        }
        String[] sources = sourceStr.split("#");
        if (sources.length < 2) {
            return null;
        }
        Long userId = NumberUtils.toLong(sources[0], -1);
        Integer cacheTime = NumberUtils.toInt(sources[1], 7200);

        // 用户信息
        User user = null;
        String userStr = redisCache.getString(FrontConst.USER_ACCESSTOKEN_USER + accessToken);
        if (StringUtils.isBlank(userStr)) {
            user = userDao.findSingle(userId);
        } else {
            user = JSON.parseObject(userStr, User.class);
            user.setId(userId);
        }

        // 唯一标识
        String md5UserId = FrontConst.USER_MD5_USERID + CodecUtil.buildHexSignMD5(FrontConst.USER_USERID_ACCESSTOKEN + user.getId().toString());

        redisCache.set(FrontConst.USER_HEXUSERID + accessToken, hexUserId, cacheTime);
        redisCache.set(md5UserId, accessToken, cacheTime);
        redisCache.set(FrontConst.USER_ACCESSTOKEN_USER + accessToken, JSON.toJSONString(user), 24 * 60 * 60L); //用户信息缓存1天

        return user;
    }


    /**
     * 更新缓存用户信息
     * @param accessToken
     * @return
     */
    public User updateRedisUserInfo(String accessToken) {
        if (StringUtils.isBlank(accessToken)) return null;

        // 从缓存中获取加密userId
        String hexUserId = redisCache.getString(FrontConst.USER_HEXUSERID + accessToken);
        if (StringUtils.isBlank(hexUserId)) {
            return null;
        }

        // 解密
        String sourceStr = CodecUtil.buildAESDecrypt(hexUserId, businessProps.getTokenAesKey());
        if (StringUtils.isBlank(sourceStr)) {
            return null;
        }
        String[] sources = sourceStr.split("#");
        if (sources.length < 2) {
            return null;
        }
        Long userId = NumberUtils.toLong(sources[0], -1);
        // 用户信息
        User user = userDao.findSingle(userId);
        redisCache.set(FrontConst.USER_ACCESSTOKEN_USER + accessToken, JSON.toJSONString(user), 24 * 60 * 60L); //用户信息缓存1天

        return user;
    }

    public BaseResponse loginInfo(UserLoginReq userLoginReq, String pwd) {
        User user = userDao.findUserByMobileOrName(userLoginReq.getMobile());
        if (null == user) {
            return new BaseResponse(FrontRetEnum.USER_NOT_EXISTS);
        }

        if (!user.getPwd().equals(CodecUtil.buildHexSignMD5(pwd))) {
            return BaseResponse.fail("账号密码不正确");
        }

        if (user.getStatus().equals(TrueFalseEnum.FALSE.getCode())) {
            return BaseResponse.fail("账号后台管理员已锁定");
        }
        // 保存用户登录记录
       // saveUserLoginLog(user.getId(), userLoginReq.getMacAddr(), userLoginReq.getDevCode(), userLoginReq.getAppVersion(), userLoginReq.getDevModel(), userLoginReq.getDevBrand(), userLoginReq.getUserIp());

        // 返回用户信息
        return loginInfo(user);
    }

    public BaseResponse loginInfo(User user) {
        // 校验用户是否已登录,针对渠道做单设备登录，不同渠道可以同时在线
        String md5UserId = FrontConst.USER_MD5_USERID + CodecUtil.buildHexSignMD5(FrontConst.USER_USERID_ACCESSTOKEN + user.getId().toString());


        String cachedToken = redisCache.getString(md5UserId);
        if (StringUtils.isNotBlank(cachedToken)) {   // 已登录
            redisCache.del(FrontConst.USER_HEXUSERID + cachedToken);
        }


        // 随机64位字符串
        String accessToken = RandomStringUtils.randomAlphanumeric(64);
        // 加密串
        long cacheTime = businessProps.getTokenTimeout();
        String sourceStr = user.getId().toString() + "#" + cacheTime;
        String aesStr = CodecUtil.buildAESEncrypt(sourceStr, businessProps.getTokenAesKey());
        // 缓存信息
        redisCache.set(FrontConst.USER_HEXUSERID + accessToken, aesStr, cacheTime);
        redisCache.set(md5UserId, accessToken, cacheTime);


        // 登录成功，返回 access token
        WebContext.setAccessToken(accessToken);

        LoginUserResp loginUserResp = new LoginUserResp();
        try {
            BeanUtils.copyProperties(loginUserResp, user);
        } catch (Exception e) {
            log.error("UserService.loginInfo() loginUserResp copy error " + e.getMessage());
            return BaseResponse.fail("账号登录异常！请联系客服");
        }

        loginUserResp.setAccessToken(accessToken);
        //loginUserResp.setImUserSign(getImUserSign(user.getId(), user.getIdcard()));

        // 返回用户信息
        return new BaseResponse(loginUserResp);
    }

    public BaseResponse loginOut() {
        if (null == redisCache.getString(FrontConst.USER_HEXUSERID + WebContext.getAccessToken())) {
            return new BaseResponse();
        }
        User user = this.authUserIdByAccessToken(WebContext.getAccessToken());
        if (null == user) {
            return new BaseResponse();
        }

        //修改用户状态为离线
        //userDao.updateOnlineByUserId(user.getId(), OnlineEnum.OFFLINE.getCode());

        String md5UserId = FrontConst.USER_MD5_USERID + CodecUtil.buildHexSignMD5(FrontConst.USER_USERID_ACCESSTOKEN + user.getId().toString());
        redisCache.del(md5UserId);
        redisCache.del(FrontConst.USER_IM_SIGN_KEY + user.getId());
        redisCache.del(FrontConst.USER_ACCESSTOKEN_USER + WebContext.getAccessToken());
        redisCache.del(FrontConst.USER_HEXUSERID + WebContext.getAccessToken());
        return new BaseResponse();
    }

    public BaseResponse modifyPwd(Long userId, String oldPwd, String newPwd) {
        User user = userDao.findSingle(userId);
        if (null == user) {
            return BaseResponse.fail("用户不存在！");
        }

        // 旧密码校验
        if (!user.getPwd().equals(CodecUtil.buildHexSignMD5(oldPwd))) {
            return BaseResponse.fail("旧密码输入错误！");
        }

        // 更新密码
        int rows = userDao.modifyPwd(userId, CodecUtil.buildHexSignMD5(newPwd));
        if (rows <= 0) {
            return BaseResponse.FAIL;
        }

        return new BaseResponse();
    }

    /**
     * 用户注册
     *
     * @param userRegisterReq
     * @return
     */
    public BaseResponse sendPhoneCode(UserRegisterReq userRegisterReq) {
        String code = redisCache.getString(FrontConst.SYSTEM_IMG_VERIFY + userRegisterReq.getMobile());
        // 验证码比对
        if (StringUtils.isEmpty(code) || !code.equals(userRegisterReq.getCode())) {
            return BaseResponse.fail("验证码错误");
        }

        //移除缓存
        redisCache.del(FrontConst.SYSTEM_IMG_VERIFY + userRegisterReq.getMobile());
        // 查看用户是否存在
        User user = userDao.findUserByMobileOrName(userRegisterReq.getMobile());
        if (Objects.nonNull(user) && userRegisterReq.getResType() == 1) {
            // 判断用户账号是否正常
            if (user.getStatus().equals(TrueFalseEnum.FALSE.getCode())) {
                return BaseResponse.fail("账号后台管理员已锁定");
            }
            // 保存用户登录记录
           // saveUserLoginLog(user.getId(), userRegisterReq.getMacAddr(), userRegisterReq.getDevCode(), userRegisterReq.getAppVersion(), userRegisterReq.getDevModel(), userRegisterReq.getDevBrand(), userRegisterReq.getUserIp());
            // 返回用户信息
            return loginInfo(user);
        } else if (Objects.isNull(user)) {
            user = new User();
            user.setMobile(userRegisterReq.getMobile()); // 手机号
            String pwd = StringUtils.isEmpty(userRegisterReq.getPwd()) ? businessProps.getInitialPass() : userRegisterReq.getPwd();
            user.setPwd(CodecUtil.buildHexSignMD5(pwd)); // 密码
            User u = saveNewUser(user);
            // 保存用户登录记录
            //saveUserLoginLog(u.getId(), userRegisterReq.getMacAddr(), userRegisterReq.getDevCode(), userRegisterReq.getAppVersion(), userRegisterReq.getDevModel(), userRegisterReq.getDevBrand(), userRegisterReq.getUserIp());
            return loginInfo(u);
        } else {
            return BaseResponse.fail("账号已存在");
        }
    }

    /**
     * 生成图形验证码
     *
     * @param phone
     * @param response
     */
    public void getRandcode(String phone, HttpServletResponse response) {
        // 创建Kaptcha配置
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width", "200");
        properties.setProperty("kaptcha.image.height", "50");
        properties.setProperty("kaptcha.textproducer.char.string", "0123456789");
        Config config = new Config(properties);

        // 创建Kaptcha实例
        DefaultKaptcha kaptcha = new DefaultKaptcha();
        kaptcha.setConfig(config);

        // 生成验证码
        String text = kaptcha.createText();
        BufferedImage image = kaptcha.createImage(text);
        long cacheTime = businessProps.getCodeTimeOut();
        redisCache.set(FrontConst.SYSTEM_IMG_VERIFY + phone, text, cacheTime);
        // 保存验证码图片
        try {
            ImageIO.write(image, "png", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 验证图形验证码
     *
     * @param phone
     * @param verifyCode
     * @return
     */
    public BaseResponse inspectImgVerify(String phone, String verifyCode) {
        String code = redisCache.getString(FrontConst.SYSTEM_IMG_VERIFY + phone);

        if (StringUtils.isEmpty(code) || !code.equals(verifyCode)) {
            return BaseResponse.fail("验证码输入有误");
        }

        // 产生验证码
        int smsCode = new Random().nextInt(9000) + 1000;

        // 验证手机号码格式是否正确
        boolean isValid = RegexUtils.isMobile(phone);
        if (!isValid) {
            return BaseResponse.fail("手机格式有误成功");
        }
        // 发送短信验证码
        if (businessProps.isProEnv()) {
            SendSms.send(phone, Integer.toString(smsCode));
        } else {
            smsCode = 6666;
        }
        log.info("发送短信验证码:" + smsCode);
        // 缓存短信验证码
        redisCache.set(FrontConst.SYSTEM_IMG_VERIFY + phone, Integer.toString(smsCode), businessProps.getCodeTimeOut());
        return BaseResponse.success("短信验证码发送成功");

    }


    /**
     * 验证短信验证码是否正确
     *
     * @param phone
     * @param code
     * @return
     */
    public BaseResponse checkSmsCode(String phone, String code) {
        String redisKey = redisCache.getString(FrontConst.SYSTEM_IMG_VERIFY + phone);
        if (StringUtils.isEmpty(code) || !code.equals(code)) {
            return BaseResponse.fail("验证码输入有误");
        } else {
            redisCache.del(redisKey);
            return BaseResponse.success("验证码正确");
        }
    }


















    /**
     * 重置密码
     *
     * @param userRegisterReq
     * @return
     */
    public BaseResponse resetPwd(UserRegisterReq userRegisterReq) {
        String code = redisCache.getString(FrontConst.SYSTEM_IMG_VERIFY + userRegisterReq.getMobile());
        // 验证码比对
        if (StringUtils.isEmpty(code) || !code.equals(userRegisterReq.getCode())) {
            return BaseResponse.fail("验证码错误");
        }
        // 查看用户是否存在
        User user = userDao.findUserByMobileAndIsDeleted(userRegisterReq.getMobile(), 0);
        if (Objects.isNull(user)) {
            return BaseResponse.fail("用户不存在");
        }
        // 判断用户账号是否正常
        if (user.getStatus().equals(TrueFalseEnum.FALSE.getCode())) {
            return BaseResponse.fail("账号后台管理员已锁定");
        }
        // 更新密码
        int rows = userDao.modifyPwd(user.getId(), CodecUtil.buildHexSignMD5(userRegisterReq.getPwd()));
        if (rows <= 0) {
            return BaseResponse.FAIL;
        }
        return BaseResponse.success("重置成功");


    }


   /* public BaseResponse weixinLogin(TLoginLog loginLog) {
        try {
            // 获取微信信息
            JSONObject userObject = PayUtil.isAccessTokenIsInvalid(StaticConstProps.wxAppId, StaticConstProps.wxAppSecret, loginLog.getCode());
            if (userObject == null) {
                return new BaseResponse(FrontRetEnum.USER_LOGIN_FAIL);
            }
            User user = userDao.findUserByWxOpenId(userObject.getString("openid"));
            if (Objects.nonNull(user)) {
                // 判断用户账号是否正常
                if (user.getLockType() == LockTypeEnum.SUPER_LOCK.getKey()) {
                    return new BaseResponse(FrontRetEnum.USER_IS_LOCKED);
                }
                user.setOnline(OnlineEnum.ONLINE.getCode());
                userDao.saveAndFlush(user);
                // 保存用户登录记录
                saveUserLoginLog(user.getId(), loginLog.getMacAddr(), loginLog.getDevCode(), loginLog.getAppVersion(), loginLog.getDevModel(), loginLog.getDevBrand(), loginLog.getUserIp());
                // 返回用户信息
                return loginInfo(user);
            }
            user = new User();
            user.setPwd(CodecUtil.buildHexSignMD5(businessProps.getInitialPass())); // 密码
            user.setWxOpenId(userObject.getString("openid"));
            User u = saveNewUser(user);
            // 保存用户登录记录
            saveUserLoginLog(u.getId(), loginLog.getMacAddr(), loginLog.getDevCode(), loginLog.getAppVersion(), loginLog.getDevModel(), loginLog.getDevBrand(), loginLog.getUserIp());
            // 返回用户信息
            return loginInfo(u);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信登录错误", e);
        }
        return new BaseResponse(FrontRetEnum.USER_LOGIN_FAIL);
    }*/



    /**
     * 新增用户
     *
     * @param user
     * @return
     */
    public User saveNewUser(User user) {
        // 保存新用户
        User uu =  userDao.save(user);
        return user;
    }

    public BaseResponse modifyBindModile(String newMobile, String smsCode) {

        User newMobileUser = userDao.findUserByMobileOrName(newMobile);
        if(newMobileUser != null){
            return BaseResponse.fail("当前手机号码已经绑定用户："+newMobileUser.getNickname()+",不能再次绑定!");
        }

        String redisCode = redisCache.getString(FrontConst.SYSTEM_IMG_VERIFY + newMobile);
        if (smsCode.equals(redisCode)) {

            User userToken = UserTokenUtil.getUser();

            User user = userDao.findSingle(userToken.getId());
            user.setMobile(newMobile);
            userDao.save(user);

            redisCache.del(FrontConst.SYSTEM_IMG_VERIFY + newMobile);

            return BaseResponse.success("修改成功，请重新登录！");
        } else {
            return BaseResponse.fail("验证码错误");
        }


    }

    public BaseResponse extract(Long userId, UserExtractReq req) {
        // 提现缓存key
        int cacheTime = 10;  // 秒
        String cacheKey = "extract_" + userId;
        // 缓存是否存在
        String cacheVal = redisCache.getString(cacheKey);
        if(StringUtils.isNotBlank(cacheVal)) {
            return BaseResponse.fail("操作过于频繁，请稍后重试！");
        } else {
            // 缓存请求
            redisCache.set(cacheKey, userId.toString(), cacheTime);
        }


        Long dataId = IdSignUtil.checkSign(req.getExtractAddressSign());
        if (null == dataId) {
            return BaseResponse.ILLEGAL_REQUEST;
        }

        UserBankCard bankCard = userBankCardDao.findSingle(dataId);
        if(bankCard == null){
            return BaseResponse.fail("提现账户不存在！");
        }


        if (req.getWithdrawalMoney().compareTo(BigDecimal.ZERO) <= 0) {
            return BaseResponse.fail("请输入正确的提现金额");
        }

        if (req.getWithdrawalMoney().compareTo(new BigDecimal(50)) < 0 || req.getWithdrawalMoney().compareTo(new BigDecimal(10000)) > 0) {
            return BaseResponse.fail("提现金额最低50 最高10000");
        }

        if (!(req.getWithdrawalMoney().compareTo(new BigDecimal("50")) == 0
                || req.getWithdrawalMoney().divideAndRemainder(new BigDecimal("100"))[1].compareTo(BigDecimal.ZERO) == 0)) {
            return BaseResponse.fail("提现金额只能50 或者整百！");
        }



        AccountTypeEnum accountTypeEnum = AccountTypeEnum.val(req.getAccountType());    // 账户类型
        if(null == accountTypeEnum) {
            return BaseResponse.fail("提现账户类型错误！2 返佣积分 4 签到积分");
        }

        String rateStr = systemService.getSysConfig(SysConfigConst.SYSTEM_SETUP_APPLY_WITHDRAWAL);
        BigDecimal rate = new BigDecimal(rateStr);

        //计算提现金额
        BigDecimal applyGoldRate = req.getWithdrawalMoney().multiply(new BigDecimal("10")).multiply(rate).divide(new BigDecimal("100")); //手续费
        BigDecimal applyGoldTotle = applyGoldRate.add(req.getWithdrawalMoney().multiply(new BigDecimal("10"))); //提现总金额

        // 用户余额信息
        User user = userDao.findSingle(userId);



        // 计算金额
        BigDecimal price = null;            // 操作前金额
        BigDecimal refreshPrice = null;     // 操作后金额
        String title = "";
        String mark = "";
        if(AccountTypeEnum.BROKERAGE == accountTypeEnum) { // 佣金
            price = user.getBrokerage();

            if (applyGoldTotle.compareTo(price) > 0) {
                return BaseResponse.fail("佣金积分不足");
            }

            // 扣除
            int rows = userDao.subtractBrokerage(userId, applyGoldTotle);
            if(rows <= 0) {
                return new BaseResponse(FrontRetEnum.USER_BALANCE_NOT_ENOUGH);
            }
            refreshPrice = user.getBrokerage().subtract(applyGoldTotle);

            title = "佣金积分提现";
            mark = "佣金积分提现，扣除佣金积分" + applyGoldTotle;
        } else if(AccountTypeEnum.INTEGRAL == accountTypeEnum) { // 签到积分提现
            price = user.getIntegral();
            if (applyGoldTotle.compareTo(price) > 0) {
                return BaseResponse.fail("签到积分不足");
            }
            // 扣除
            int rows = userDao.subtractIntegral(userId, applyGoldTotle);
            if(rows <= 0) {
                return new BaseResponse(FrontRetEnum.USER_BALANCE_NOT_ENOUGH);
            }
            refreshPrice = user.getIntegral().subtract(applyGoldTotle);

            title = "签到积分提现";
            mark = "签到积分提现，扣除签到积分" + applyGoldTotle;
        }  else {
            return BaseResponse.fail("账户类型错误！");
        }

        // 提现记录
        String orderSn = RandomUtil.generateId7OrderNo("E", userId);
        UserExtract userExtract = new UserExtract();
        userExtract.setUid(userId);
        userExtract.setExtractPrice(req.getWithdrawalMoney());
        userExtract.setLessIntegral(applyGoldTotle);
        userExtract.setTixianFee(applyGoldRate);
        userExtract.setType(req.getAccountType());
        userExtract.setOrderSn(orderSn);
        userExtract.setAccount(bankCard.getAccount());
        userExtract.setBankcardId(bankCard.getId());
        userExtract.setBankReserveTel(bankCard.getBankReserveTel());
        userExtract.setRealname(bankCard.getRealname());
        userExtract.setAlipayImg(bankCard.getAlipayImg());
        userExtract.setIdnumber(bankCard.getIdnumber());
        userExtractDao.save(userExtract);

        // 保存交易记录
       if(AccountTypeEnum.INTEGRAL == accountTypeEnum) {//佣金体现写入佣金记录表
           userIntegtralBillService.addUserIntegralBill(userId,userExtract.getId(),user.getIntegral(),applyGoldTotle,refreshPrice,
                    BillTableNameEnum.EXTRACT.getKey(), IncomeTypeEnum.EXPEND.getKey(),mark);
        }else{
            userBillService.addUserBill(userId, applyGoldTotle, userExtract.getId(), BillTableNameEnum.EXTRACT.getKey(), user.getBrokerage(),
                    refreshPrice, IncomeTypeEnum.EXPEND.getKey(), req.getAccountType(),
                    title, mark);
        }


        return new BaseResponse();
    }

    public BaseResponse pageExtract(Long userId) {
        Page page = userExtractSQLDao.pageExtract(userId);
        return new BaseResponse(page);
    }


    public BaseResponse incomeStatistic(Long userId) {
        UserIncomeStatisticVo incomeStatisticVo = null;

        // 缓存key
        int cacheTime = 20;  // 秒
        String cacheKey = "incomeStatistic_" + userId;
        // 缓存是否存在
        String cacheVal = redisCache.getString(cacheKey);
        if(StringUtils.isNotBlank(cacheVal)) {
            incomeStatisticVo = JSON.parseObject(cacheVal, UserIncomeStatisticVo.class);
            return new BaseResponse(incomeStatisticVo);
        }

        Date now = new Date();
        Date today = DateUtil.cutDateYYYYMMDD000000(now);

        // 用户信息
        User user = userDao.findSingle(userId);

        // 累计已提现
        BigDecimal totalExtract = userExtractDao.sumAmount(userId);

        // 今日未拼中收入
        BigDecimal todayNotPzIncome = new BigDecimal("0");

        // 今日团队收入
        BigDecimal todayTeamIncome =  new BigDecimal("0");

        // 昨日收入
        BigDecimal lastdayBroIncome = new BigDecimal("0");

        // 今日佣金收入
        BigDecimal todayBroIncome = todayNotPzIncome.add(todayTeamIncome);

        // 汇总返回
        incomeStatisticVo = new UserIncomeStatisticVo();
        incomeStatisticVo.setBrokerage(user.getBrokerage());
        incomeStatisticVo.setTotalExtract(totalExtract);
        incomeStatisticVo.setLastdayBroIncome(lastdayBroIncome);
        incomeStatisticVo.setTodayBroIncome(todayBroIncome);
        incomeStatisticVo.setTodayNotPzIncome(todayNotPzIncome);
        incomeStatisticVo.setTodayTeamIncome(todayTeamIncome);

        // 缓存返回值
        redisCache.set(cacheKey, JSON.toJSONString(incomeStatisticVo), cacheTime);

        return new BaseResponse(incomeStatisticVo);
    }


    public BaseResponse userCenter(Long userId) {
        UserCenterVo userCenterVo = null;

        // 缓存key
        int cacheTime = 5;  // 秒
        String cacheKey = "userCenter_" + userId;
        // 缓存是否存在
        String cacheVal = redisCache.getString(cacheKey);
        if(StringUtils.isNotBlank(cacheVal)) {
            userCenterVo = JSON.parseObject(cacheVal, UserCenterVo.class);
            return new BaseResponse(userCenterVo);
        }

        User user = userDao.findSingle(userId);

        userCenterVo = new UserCenterVo();
        userCenterVo.setUser(user);

        //我的关注
        userCenterVo.setCollectNum(collectDao.myCollectCount(userId));

        //我的订单
        userCenterVo.setOrderNum(storeOrderDao.myOrderCount(userId));

        //待支付订单
        userCenterVo.setPayOrderNum(storeOrderDao.myPayOrderCount(userId));


        userCenterVo.setWithdrawalRate(systemService.getSysConfig(SysConfigConst.SYSTEM_SETUP_APPLY_WITHDRAWAL));

        // 缓存返回值
        redisCache.set(cacheKey, JSON.toJSONString(userCenterVo), cacheTime);

        return new BaseResponse(userCenterVo);
    }

    public BaseResponse modifyUserInfo(Long userId, ModifyUserInfoReq req) {
        int rows = userDao.updateInfo(userId, req.getNickname());
        if(rows <= 0) {
            return BaseResponse.FAIL;
        }
        //修改头像  更新登录用户缓存数据
        updateRedisUserInfo(WebContext.getAccessToken());
        return new BaseResponse();
    }


    public BaseResponse modifyUsePhoto(Long userId, ModifyUsePhotoReq req) {
        int rows = userDao.updateAvatar(userId, req.getAvatar());
        if(rows <= 0) {
            return BaseResponse.FAIL;
        }
        updateRedisUserInfo(WebContext.getAccessToken());

        return new BaseResponse(req.getAvatar());
    }


    public BaseResponse statPromoter(Long userId){
        int rows = userDao.statPromoter(userId);
        return new BaseResponse(rows);
    }


    public BaseResponse updateCollect(Long id, String type) {

        Long userId = UserTokenUtil.getUser().getId();

        if("0".equals(type)){//收藏
            Collect oldCollect = collectDao.queryCollectByUserIdAndProductId(userId, id);
            if(oldCollect != null){
                return BaseResponse.fail("请勿重复收藏");
            }
            Collect collect = new Collect();
            collect.setUserId(userId);
            collect.setProductId(id);
            collect.setCreateTime(new Date());
            collectDao.save(collect);
            return BaseResponse.success("收藏成功");
        }else{//取消收藏
            Collect oldCollect = collectDao.queryCollectByUserIdAndProductId(userId, id);
            if(oldCollect == null){
                return BaseResponse.fail("商品已取消收藏");
            }
            collectDao.delete(oldCollect);
            return BaseResponse.success("取消收藏成功");
        }

    }

    /**
     * 商品反馈
     * @param userId
     * @param productFeedBackReq
     * @return
     */
    public BaseResponse productFeedback(Long userId, ProductFeedBackReq productFeedBackReq) {

        ProductFeedback productFeedback = new ProductFeedback();
        productFeedback.setUserId(userId);
        productFeedback.setCreateTime(new Date());
        productFeedback.setName(productFeedBackReq.getName());
        productFeedback.setContent(productFeedBackReq.getContent());
        productFeedback.setPrivce(productFeedBackReq.getPrivce());
        productFeedback.setImg(productFeedBackReq.getImg());
        productFeedbackDao.save(productFeedback);
        return BaseResponse.success("反馈成功");

    }

    /**
     * 我的收藏
     * @param userId
     * @return
     */
    public BaseResponse collectPage(Long userId) {
      return new BaseResponse(collectSQLDao.page(userId));
    }

    public Boolean isCollect(User user,Long id) {

        if(user == null) { //未登录 显示为未收藏
            return false;
        }
        Collect oldCollect = collectDao.queryCollectByUserIdAndProductId(user.getId(), id);
        if(oldCollect == null){
            return false;
        }else{
            return true;
        }
    }
}
